package org.springframework.boot.autoconfigure.netty.security;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.netty.support.JWTInfo;
import org.springframework.boot.autoconfigure.netty.support.JwtUtils;
import org.springframework.boot.autoconfigure.netty.support.RsaUtils;

import java.security.PublicKey;
import java.util.Arrays;

public class ShiroRealm extends AuthorizingRealm implements InitializingBean {


    private PublicKey publicKey = null;


    @Override
    public boolean supports(AuthenticationToken token) {

        return token instanceof JwtToken;
    }
 
    /**
     * 用户名信息验证
     * @param authcToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {

        JWTInfo jwtInfo = new JWTInfo();

        //1. 校验username
        JwtToken jwtToken = (JwtToken) authcToken;
        if (jwtToken.getPrincipal() == null) {
            throw new AccountException("JWT token参数异常！");
        }

        //2. 校验accesstoken是否过期
        if(!JwtUtils.validatorToken(jwtToken.getCredentials().toString(),publicKey)){
            //throw new AuthenticationException("Token expired or incorrect.");
            return new SimpleAuthenticationInfo(jwtInfo, "anonymous", getName());
        }

        //3. 解析用户信息
        try {
            jwtInfo = JwtUtils.getInfoFromToken(jwtToken.getCredentials().toString(),publicKey);
        } catch (Exception e) {
           // throw new AuthenticationException("publicKey not found");
            return new SimpleAuthenticationInfo(jwtInfo, "anonymous", getName());
        }

        //4. 返回认证信息
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(jwtInfo, jwtToken.getPrincipal(), getName());
        return info;

    }
 
    /**
     * 检查用户权限
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        // 获取当前用户
        JWTInfo currentUser = (JWTInfo) SecurityUtils.getSubject().getPrincipal();
        // JWTInfo currentUser = (JWTInfo) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(currentUser.getAuthentication().getRoles());
        authorizationInfo.setStringPermissions(currentUser.getAuthentication().getPermissions());
        return authorizationInfo;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //1. 获取公钥
        try {
            publicKey  = RsaUtils.getPublicKey("rsa/id_rsa.pub");
        } catch (Exception e) {
            throw new AuthenticationException("publicKey not found");
        }
    }

}